package com.xuecheng.common.exception;


import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.code.ErrorCode;
import com.xuecheng.common.domain.response.RestErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 微服务业务模块全局异常处理器
 *  使用 Spring 中提供的注解实现对全局异常信息的捕获
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

	/**
	 * 处理可预知异常（业务模块中的异常信息）
	 * @param businessException {@link BusinessException} 业务异常类
	 * @return RestErrorResponse - 相应错误信息封装类，封装错误代码(code) 和 错误信息（desc）
	 */
	@ResponseBody
	@ExceptionHandler(value = BusinessException.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public RestErrorResponse customException(BusinessException businessException) {

		//0.将错误信息记录到日志中
		log.error("【系统异常】{}", businessException.getMessage(), businessException);

		//1.获得异常信息属性
		ErrorCode errorCode = businessException.getErrorCode();

		//2.将异常信息属性的 错误代码(code) 和 错误信息（desc）封装到 RestErrorResponse 中
		return new RestErrorResponse(errorCode);
	}


	/**
	 * 处理不可预知异常（微服务框架抛出不可预知异常类型）
	 * @param exception  {@link Exception} 异常类
	 * @return RestErrorResponse - 相应错误信息封装类，封装错误代码(code) 和 错误信息（desc）
	 */
	@ResponseBody
	@ExceptionHandler(value = Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public RestErrorResponse exception(Exception exception) {

		//0.将错误信息记录到日志中
		log.error("【系统异常】{}", exception.getMessage(), exception);

		//1.将异常信息属性的 错误代码(code) 和 错误信息（desc）封装到 RestErrorResponse 中
		return new RestErrorResponse(String.valueOf(CommonErrorCode.UNKOWN.getCode()),
				CommonErrorCode.UNKOWN.getDesc() + ":" + exception.getMessage());
	}
}
